package com.wx.service.impl;

import com.google.common.collect.Lists;
import com.wx.common.SecurityUser;
import com.wx.constants.Constants;
import com.wx.domain.dto.AuthUserDto;
import com.wx.domain.vo.MenuTreeVo;
import com.wx.entity.SysMenu;
import com.wx.entity.SysRoleMenu;
import com.wx.exception.BusinessException;
import com.wx.mapper.SysMenuMapper;
import com.wx.service.SysMenuService;
import com.wx.service.SysRoleMenuService;
import com.wx.utils.SnowFlakeUtil;
import com.wx.utils.TreeUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>Title:	  MenuServiceImpl <br/> </p>
 * <p>Description 菜单service实现 <br/> </p>
 * <p>Company:    陕西天璇信息科技有限公司  <br/> </p>
 *
 * @Author <a href="xinglinglove1029@163.com"/>杨文生</a>  <br/>
 * @Date 2018/3/23 16:57
 */
@Service
public class SysMenuServiceImpl extends BaseServiceImpl<SysMenu> implements SysMenuService {
    
    @Resource
    private SysMenuMapper menuMapper;

    @Resource
    private SysRoleMenuService roleMenuService;


    @Override
    @Transactional
    public int saveMenuInfo(SysMenu menu, AuthUserDto authUserDto) {
        SysMenu querMenu = new SysMenu();
        querMenu.setId(menu.getPid());
        querMenu.setDelFlag(Constants.DELETE_NO);
        SysMenu mn = menuMapper.selectOne(querMenu);
        if (Objects.isNull(mn)) {
            throw new BusinessException("父菜单信息不存在");
        }
        menu.setLevel(mn.getLevel()+1);
        menu.setCreator(authUserDto.getRealName());
        menu.setCreateBy(authUserDto.getUserId());
        menu.setUpdater(authUserDto.getRealName());
        menu.setUpdateBy(authUserDto.getUserId());
        menu.setId(SnowFlakeUtil.getStringId());
        int result = menuMapper.insertSelective(menu);

        SysMenu query = new SysMenu();
        query.setMenuCode(menu.getMenuCode());
        SysMenu queryMenu = menuMapper.selectOne(query);
        SysRoleMenu superRoleMenu = new SysRoleMenu();
        superRoleMenu.setRoleId(Constants.Sys.SUPER_MANAGER);
        superRoleMenu.setMenuId(queryMenu.getId());
        roleMenuService.save(superRoleMenu);
        return result;
    }

    @Override
    public int modifyMenu(SysMenu menu, AuthUserDto authUserDto) {
        SysMenu querMenu = new SysMenu();
        querMenu.setId(menu.getId());
        querMenu.setDelFlag(Constants.DELETE_NO);
        SysMenu mn = menuMapper.selectOne(querMenu);
        if (Objects.isNull(mn)) {
            throw new BusinessException("菜单信息不存在");
        }
        menu.setCreator(authUserDto.getRealName());
        menu.setCreateBy(authUserDto.getUserId());
        menu.setUpdater(authUserDto.getRealName());
        menu.setUpdateBy(authUserDto.getUserId());
        return menuMapper.updateByPrimaryKeySelective(menu);
    }

    @Override
    public int disableMenuById(String id, AuthUserDto authUserDto) {
        SysMenu querMenu = new SysMenu();
        querMenu.setId(id);
        querMenu.setDelFlag(Constants.DELETE_NO);
        SysMenu menu = menuMapper.selectOne(querMenu);
        if (Objects.isNull(menu)) {
            throw new BusinessException("菜单信息不存在");
        }
        if (!Constants.ENABLE.equals(menu.getStatus())) {
            throw new BusinessException("不是启用状态的不能禁用");
        }
        querMenu.setStatus(Constants.DISABLE);
        querMenu.setUpdater(authUserDto.getRealName());
        querMenu.setUpdateBy(authUserDto.getUserId());
        querMenu.setUpdateDate(new Date());
        return menuMapper.updateByPrimaryKeySelective(querMenu);
    }

    @Override
    public int enableMenuById(String id, AuthUserDto authUserDto) {
        SysMenu querMenu = new SysMenu();
        querMenu.setId(id);
        querMenu.setDelFlag(Constants.DELETE_NO);
        SysMenu menu = menuMapper.selectOne(querMenu);
        if (Objects.isNull(menu)) {
            throw new BusinessException("菜单信息不存在");
        }
        if (!Constants.DISABLE.equals(menu.getStatus())) {
            throw new BusinessException("不是禁用状态的不能启用");
        }
        querMenu.setStatus(Constants.ENABLE);
        querMenu.setUpdater(authUserDto.getRealName());
        querMenu.setUpdateBy(authUserDto.getUserId());
        querMenu.setUpdateDate(new Date());
        return menuMapper.updateByPrimaryKeySelective(querMenu);
    }

    @Override
    public int deleteMenuById(String id, AuthUserDto authUserDto) {
        SysMenu querMenu = new SysMenu();
        querMenu.setId(id);
        querMenu.setDelFlag(Constants.DELETE_NO);
        SysMenu menu = menuMapper.selectOne(querMenu);
        if (Objects.isNull(menu)) {
            throw new BusinessException("菜单信息不存在");
        }
        // 查询其是否还存在子节点
        SysMenu selectMenu = new SysMenu();
        selectMenu.setPid(id);
        int count = menuMapper.selectCount(selectMenu);
        if(count > 0){
            throw new BusinessException("该菜单下还存在子菜单不能将其删除");
        }
        querMenu.setDelFlag(Constants.DELETE_YES);
        querMenu.setUpdater(authUserDto.getRealName());
        querMenu.setUpdateBy(authUserDto.getUserId());
        querMenu.setUpdateDate(new Date());
        return menuMapper.updateByPrimaryKeySelective(querMenu);
    }

    @Override
    public List<MenuTreeVo> getMenuTree(String menuId) {
        List<SysMenu> menuList = menuMapper.selectAllMenu();
        Map<String, String> menuMap = menuList.stream().collect(Collectors.toMap(SysMenu::getId, SysMenu::getMenuName));
        List<MenuTreeVo> trees = Lists.newArrayList();
        MenuTreeVo node = null;
        for (SysMenu menu : menuList) {
            node = new MenuTreeVo();
            BeanUtils.copyProperties(menu, node);
            node.setId(menu.getId());
            node.setParentId(menu.getPid());
            String parentMenuName = menuMap.get(menu.getPid());
            node.setParentMenuName(parentMenuName);
            node.setNumber(menu.getNumber());
            trees.add(node);
        }
        return TreeUtil.bulid(trees,menuId) ;
    }

    @Override
    public SysMenu getMenuById(String menuId) {
        return menuMapper.selectByPrimaryKey(menuId);
    }

    @Override
    public List<MenuTreeVo> getMenuTreeByUserId(SecurityUser securityUser) {
        List<String> roleIds = securityUser.getOwnRoles();
        List<SysMenu> menuList = roleMenuService.getMenuByRoleIds(roleIds);
        if(securityUser.isAdmin()){
           menuList = menuMapper.selectAllMenu();
        }
        Map<String, String> menuMap = menuList.stream().collect(Collectors.toMap(SysMenu::getId, SysMenu::getMenuName));
        List<MenuTreeVo> trees = Lists.newArrayList();
        MenuTreeVo node = null;
        for (SysMenu menu : menuList) {
            node = new MenuTreeVo();
            BeanUtils.copyProperties(menu, node);
            node.setParentId(menu.getPid());
            String parentMenuName = menuMap.get(menu.getPid());
            node.setParentMenuName(parentMenuName);
            node.setNumber(menu.getNumber());
            trees.add(node);
        }
        return TreeUtil.bulid(trees,Constants.Sys.ROOT) ;
    }

    @Override
    public List<SysMenu> getOwnMenuModule(List<String> roleIds) {
        return roleMenuService.getOwnMenuModule(roleIds);
    }

    @Override
    public MenuTreeVo getMenuTreeIncludeSelf(String menuId) {
        List<SysMenu> menuList = menuMapper.selectAllMenu();
        Map<String, String> menuMap = menuList.stream().collect(Collectors.toMap(SysMenu::getId, SysMenu::getMenuName));
        List<MenuTreeVo> trees = Lists.newArrayList();
        MenuTreeVo node = null;
        MenuTreeVo currentMenu = new MenuTreeVo();
        currentMenu.setId(menuId);
        for (SysMenu menu : menuList) {
            node = new MenuTreeVo();
            BeanUtils.copyProperties(menu, node);
            node.setId(menu.getId());
            node.setParentId(menu.getPid());
            String parentMenuName = menuMap.get(menu.getPid());
            node.setParentMenuName(parentMenuName);
            node.setNumber(menu.getNumber());
            trees.add(node);
            if(menuId.equals(menu.getId())){
                BeanUtils.copyProperties(menu, currentMenu);
                currentMenu.setParentId(menu.getPid());
            }
        }
        return TreeUtil.findChildren(currentMenu, trees);
    }

    @Override
    public List<SysMenu> queryAllMenu() {
        return menuMapper.selectAllMenu();
    }

}
